<template>
    <el-table
        v-loading="tableLoading"
        :data="table_data"

        :row-key="table_tree.key"
        :lazy="table_tree.is_lazy"
        :load="table_tree.load_func"
        :default-expand-all="table_tree.is_all_expand"
        :expand-row-keys="table_tree.expand_ids"
        :tree-props="table_tree.props"
        :indent="table_tree.indent"

        :highlight-current-row="highlight_current_row"
        :row-style="row_style"
        :cell-style="cell_style"
        :header-row-style="header_row_style"
        :header-cell-style="header_cell_style"
        :border="is_border"
        :stripe="is_stripe"
        :fit="is_fit"
        :show-summary="is_sum"
        :summary-method="sum_method"
        :show-header="is_show_header"

        @expand-change="clk_table_expand"
        @row-click="clk_table_row"

        class="bsk-main-table"
        :style="`width: 100%`"
        :ref="table_ref"
    >
        <!--    @cell-dblclick="dblclick"-->

        <!-- table 展开行 -->
        <el-table-column type="expand" v-if="is_show_expand">
            <template slot-scope="props">
                <el-form label-position="left" class="demo-table-expand" :label-width="expand_label_width + 'px'">
                    <template v-for="(item_expand, index) in table_expand">
                        <el-form-item
                            v-if="(!item_expand.hasOwnProperty('is_hide') || !item_expand.is_hide) && props.row.hasOwnProperty('expand')"
                            :label="item_expand.label">
                            <!-- 数据转换 -->
                            <span v-if="typeof item_expand.render === 'function'">
                                <template v-if="item_expand.hasOwnProperty('is_parent') && item_expand.is_parent">
                                    {{ item_expand.render(props.row, item_expand.prop, item_expand) }}
                                </template>
                                <template v-else>
                                    {{ item_expand.render(props.row.expand, item_expand.prop, item_expand, props.row) }}
                                </template>
                            </span>

                            <!-- 数据覆盖 -->
                            <span
                                v-else-if="typeof item_expand.render === 'string' || typeof item_expand.render === 'number'">
                                {{ item_expand.render }}
                            </span>

                            <!-- 标签 -->
                            <span v-else-if="typeof item_expand.tag === 'function'">
                                <el-tag size="mini" type="item_expand.tag(props.row.expand[item.prop]).k"
                                        @click="typeof item_expand.click === 'function'
                                        ? item_expand.click(props.row.expand, item_expand.prop, item_expand, props.row)
                                        : () => {}">
                                  {{ item_expand.tag(props.row.expand[item_expand.prop]).v }}
                                </el-tag>
                            </span>
                            <!-- 父级属性 -->
                            <span v-else-if="item_expand.hasOwnProperty('is_parent') && item_expand.is_parent"
                                  class="cell-overflow cell-overflow-elisp">
                                {{ props.row.hasOwnProperty(item_expand.prop) ? props.row[item_expand.prop] : '' }}
                            </span>
                            <!-- 原样输出 -->
                            <span v-else class="cell-overflow cell-overflow-elisp">
                                {{ props.row.hasOwnProperty('expand') && props.row.expand.hasOwnProperty(item_expand.prop)
                                    ? props.row.expand[item_expand.prop] : '' }}
                            </span>

                        </el-form-item>
                    </template>
                </el-form>
            </template>
        </el-table-column>

        <!-- table 展示数据 -->
        <template v-for="(item, index) in table_header">
            <el-table-column
                :key="index"
                :prop="item.prop"
                :label="item.label"
                :width="item.width"
                :align="item.align"
                :fixed="item.fixed"
                v-if="!item.hasOwnProperty('is_hide') || !item.is_hide"
                show-overflow-tooltip
            >
                <!-- 展示二级表头 -->
                <template v-for="child in item.child">
                    <el-table-column :key="child.id" :label="child.label" :align="child.align" :width="child.width">
                        <template slot-scope="scope">
                            <span v-if="typeof child.render === 'function'">
                                {{ child.render(scope.row, child.prop, item) }}
                            </span>

                            <span v-else class="cell-overflow">
                                {{ scope.row[child.prop] }}
                            </span>
                        </template>
                    </el-table-column>
                </template>

                <template slot-scope="scope">

                    <!-- 按钮切换 -->
                    <span v-if="item.switch">
                        <el-switch
                            :active-value="typeof scope.row[item.prop] == 'boolean' ? true : 1"
                            :inactive-value="typeof scope.row[item.prop] == 'boolean' ? false : 0"
                            v-model="scope.row[item.prop]"
                            @change="clk_switch(scope.row, item.prop)"
                            :disabled="item.is_disabled || !item.is_enabled"
                        ></el-switch>
                    </span>

                    <!-- 数据转换 -->
                    <span v-else-if="typeof item.render === 'function'">
                        {{ item.render(scope.row, item.prop, item) }}
                    </span>

                    <!-- 数据覆盖 -->
                    <span v-else-if="typeof item.render === 'string' || typeof item.render === 'number'">
                        {{ item.render }}
                    </span>

                    <!-- 标签 -->
                    <span v-else-if="typeof item.tag === 'function'">
                        <el-tag
                            size="mini"
                            :type="item.tag(scope.row[item.prop], scope.row, item.prop).k"
                            @click="typeof item.click === 'function' ? item.click(scope.row, item.prop, item) : () => {}">
                          {{ item.tag(scope.row[item.prop], scope.row, item.prop).v }}
                        </el-tag>
                    </span>

                    <!-- 自定义span -->
                    <span v-else-if="typeof item.span === 'function'"
                          :class="item.span(scope.row[item.prop], scope.row, item.prop).c"
                          @click="typeof item.click === 'function' ? item.click(scope.row, item.prop, item) : () => {}">
                        {{ item.span(scope.row[item.prop], scope.row, item.prop).v }}
                    </span>

                    <!-- 数字编辑 -->
                    <div v-else-if="item.input">
                        <el-input
                            class="edit-input"
                            v-show="parseInt(scope.$index) === parseInt(current.row) && item.prop === current.column"
                            v-model="scope.row[item.prop]"
                            @input="editing(scope.row, item.prop, item.input, $event)"
                            @change="end_edit(scope.row, item.prop)"
                            v-on:blur="close_edit"
                        ></el-input>
                        <span v-show="parseInt(scope.$index) !== parseInt(current.row) || item.prop !== current.column"
                              @dblclick="start_edit(scope.$index, item.prop, $event)"
                              class="cell-span input_span">
                            {{ scope.row[item.prop] }}
                        </span>
                    </div>

                    <!-- 双击复制 -->
                    <div v-else-if="item.copy">
                        <span @dblclick="dblclick_copy(scope.row[item.prop])" class="cell-span">
                            {{ scope.row[item.prop] }}
                        </span>
                    </div>

                    <!-- 查看明细 icon-->
                    <div v-else-if="item.view">
                        <el-button type="text" @click="item.view(scope.row, item.prop, item)">
                            {{scope.row[item.prop]}}<i class="el-icon-view el-icon--right"></i>
                        </el-button>
                    </div>

                    <span v-else class="cell-overflow">
                        {{ scope.row[item.prop] }}
                    </span>
                </template>
            </el-table-column>
        </template>

        <!-- table 操作 -->
        <el-table-column
            v-if="is_show_action"
            :label="table_action.label"
            :width="table_action.width"
            :fixed="table_action.fixed"
            :align="table_action.align"
        >
            <template slot-scope="scope" style="display: flex;justify-content: space-around">
                <!--new-->
                <!-- 小于等于3个正常渲染-->
                <template v-if="actionsLength<=10">
                    <template v-for="(item, index) in table_action.options">
                        <el-button
                            :key="index"
                            :type="item.type"
                            :size="item.size"
                            :style="`color: ${item.color};margiLeft: ${item.ml ? item.ml : 0}`"
                            style="margin-right: 0px"
                            @click="clk_button(scope.row, item.event)"
                            v-if="item.is_show"
                        >
                            <span>
                                <i :class="item.icon" style="margin-right: 0"></i>
                                {{item.label}}
                                <!--                   <span v-if="device!='mobile'">{{ item.label }}</span>-->
                            </span>
                        </el-button>
                    </template>
                </template>
                <!-- 大于三个，前两个正常渲染，后边的更多下拉-->
                <template v-if="actionsLength>10">
                    <template v-for="(item, index) in table_action.options.slice(0,9)">
                        <el-button
                            :key="index"
                            :type="item.type"
                            :size="item.size"
                            :style="`color: ${item.color};margiLeft: ${item.ml ? item.ml : 0}`"
                            style="margin-right: 0px"
                            @click="clk_button(scope.row, item.event)"
                            v-if="item.is_show">
                            <span>
                                <i :class="item.icon" style="margin-right: 0"></i>
                                {{ item.label }}
                            </span>
                        </el-button>
                    </template>

                    <template>
                        <el-dropdown size="mini" @command="(command) =>handleCommand(scope.row, command)">
                            <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
                            <el-dropdown-menu slot="dropdown" style="padding: 0 15px">
                                <el-dropdown-item v-for="(item,index) in table_action.options.slice(2,table_action.options.length+1)"
                                                  :key="index" :command="item.event">
                                    <span style="font-size: 14px;line-height: 20px" :style="`color: ${item.color}`">
                                        <i :class="item.icon" style="margin-right: 0"></i>
                                        {{item.label}}
                                    </span>
                                </el-dropdown-item>
                            </el-dropdown-menu>
                        </el-dropdown>
                    </template>
                </template>

            </template>
        </el-table-column>

    </el-table>
</template>
<script>
    import _object from "../utils/_object";
    import _function from "../utils/_function";


    export default {
        name: "table_list",
        props: {
            table_header: {
                type: Array, default: function () {
                    return []
                }
            }, //列头数据
            table_data: {
                type: Array, default: function () {
                    return []
                }
            }, //表格数据
            table_expand: {
                type: Array, default: function () {
                    return []
                }
            }, //展开结构

            table_action: {
                type: Object, default: function () {
                    return {}
                }
            }, //操作结构
            table_tree: {
                type: Object, default: function () {
                    return {}
                }
            }, //树形结构

            highlight_current_row: {type: Boolean, default: true}, //是否高亮当前行
            is_border: {type: Boolean, default: false}, //是否带有纵向边框
            is_stripe: {type: Boolean, default: false}, //是否为斑马纹
            row_style: {
                default: function () {
                    return {height: '40px'}
                }
            }, //单元格的行 style
            cell_style: {
                default: function () {
                    return {padding: '0px'}
                }
            }, //单元格的列 style
            header_row_style: {
                default: function () {
                    return {height: '40px', backgroundColor: '#4d95ff'}
                }
            }, // 表头行的style
            header_cell_style: {
                default: function () {
                    return {}
                }
            }, // 表头行的style
            is_fit: {type: Boolean, default: true}, //列的宽度是否自撑开 ,默认撑开
            is_sum: {type: Boolean, default: false}, //是否显示合计,只能在表尾显示
            is_show_header: {type: Boolean, default: true}, //是否显示表头
            table_sum_method: {type: Function, default: null}, //行点击触发事件
            table_max_height: {type: Number, default: -1}, //表格高度 在父级元素下百分比
            table_ref: {type: String, default: 'bsk_table_ref'}, //表格高度 在父级元素下百分比
            expand_label_width: {type: Number, default: 80}, //展开行label宽度

            clk_row: {
                type: Function, default: function () {
                    return {}
                }
            }, //行点击触发事件
            clk_expand: {
                type: Function, default: function () {
                    return {}
                }
            }, //点击展开行事件
            tableLoading: {type: Boolean}
        },
        data() {
            //是否有备注信息
            let is_show_expand = _object._length(this.table_expand) > 0
            //是否有操作权限
            let is_show_action = this.init_action()
            this.init_tree()
            return {
                is_show_action: is_show_action, //是否有操作权限
                is_show_expand: is_show_expand, //是否有备注信息
                max_height: undefined,

                expand_keys: [], //展开行
                current: {row: -1, column: ""},
            };
        },

        mounted() {
            this.$nextTick(() => {
                this.init_action();
                // 获取元素
                // 设置表格的高度
                if (this.table_max_height > 0) {
                    this.max_height = parseFloat(this.$refs[this.table_ref].$parent.$parent.$el.offsetHeight) * this.table_max_height
                } else if (this.table_max_height < 0) {
                    this.max_height = parseFloat(this.$refs[this.table_ref].$parent.$parent.$el.offsetHeight) * 0.81
                }
            })
        },

        methods: {

            //计算操作宽度
            init_action() {

                if (_object._length(this.table_action) === 0
                    || _object._length(this.table_action.options) === 0)
                    return false

                //设定操作属性
                this.table_action.label = this.table_action.hasOwnProperty('label') ? this.table_action.label : '操作'
                this.table_action.fixed = 'right' //this.table_action.hasOwnProperty('fixed') ? this.table_action.fixed : false //是否浮动 right

                let w = 0
                let tabelAction = this.table_action.options.length > this.actionsLength ? this.table_action.options.slice(0, this.actionsLength) : this.table_action.options;
                for (let i in tabelAction) {
                    if (!tabelAction[i].hasOwnProperty('is_show')
                        || !tabelAction[i].is_show)
                        continue

                    //设定宽度则返回 宽度设置
                    w += (tabelAction[i].label.length + 1) * 14 + 22
                    if (this.table_action.width > 0)
                        return true
                }
                if (w === 0)
                    return false

                if (w < 100)
                    w = 100

                this.table_action.width = w
                // console.log(w)
                return this.table_action.width
                // return true
            },

            //树形结构 - 以及控制展开行
            init_tree() {
                if (_object._length(this.table_tree) === 0) {
                    this.table_tree.key = ''
                    return
                }

                if (this.table_tree.hasOwnProperty('is_close') && this.table_tree.is_close) {
                    this.table_tree = {key: ''}
                    return
                }

                //设定树结构属性
                this.table_tree.key = this.table_tree.hasOwnProperty('key') ? this.table_tree.key : 'id' //渲染树形结构必须设置，展开行key
                this.table_tree.expand_ids = this.table_tree.hasOwnProperty('expand_ids') ? this.table_tree.expand_ids : [] //默认展开的行
                this.table_tree.is_all_expand = this.table_tree.hasOwnProperty('is_all_expand') ? this.table_tree.is_all_expand : false

                //属性结构
                if (this.table_tree.hasOwnProperty('is_tree') && this.table_tree.is_tree) {
                    this.table_tree.is_lazy = this.table_tree.hasOwnProperty('is_lazy') ? this.table_tree.is_lazy : false //是否懒加载
                    this.table_tree.load_func = this.table_tree.hasOwnProperty('load_func') && typeof this.table_tree.load_func == "function" ? this.table_tree.load_func : null //懒加载函数
                    this.table_tree.props = this.table_tree.hasOwnProperty('props') ? this.table_tree.props : {
                        children: 'children',
                        hasChildren: 'hasChildren'
                    } //控制树形结构
                    this.table_tree.indent = this.table_tree.hasOwnProperty('indent') ? this.table_tree.indent : 16
                }
            },

            //点击操作按钮
            clk_button(row, event) {
                this.$emit("trigger", row, event);
            },
            // 更多操作
            handleCommand(row, event) {
                this.$emit("trigger", row, event);
            },

            //按钮切换
            clk_switch(row, k) {
                let v = row[k];
                this.$emit("change", row, k, v);
            },

            //双击复制
            dblclick_copy(v) {
                _function._copy(v)
            },

            //双击编辑 - 开始编辑
            start_edit(row, column, e) {
                this.current.row = row;
                this.current.column = column;

                this.$nextTick(() => {
                    //聚焦
                    e.target.parentElement.children[0].querySelector("input").focus();
                });
            },

            //编辑中
            editing(row, k, t, e) {
                e = e + "";
                if (typeof t == "function")
                    t(row, k, e)
            },

            //编辑上报
            end_edit(row, k) {
                this.current.row = -1;
                this.current.column = "";
                let v = row[k];
                this.$emit("end_edit", row, k, v);
            },

            //关闭编辑
            close_edit(row, k) {
                this.current.row = -1;
                this.current.column = "";
            },

            //懒加载数据
            load_function(tree, treeNode, resolve) {
                //tree 父节点数据
                //treeNode 树形结构属性
                //resolve 子节点数据 加载函数
                //必须父节点存在hasChildren 为true生效，父节点存在children则不触发，直接响应子节点数据
                resolve([])
            },

            //点击表格行
            clk_table_row(row) {
                if (typeof this.clk_row == "function")
                    this.clk_row(row)

                // //点击表格展开
                // this.$refs.bsk_table_ref.toggleRowExpansion(row);
            },

            //点击展开行
            clk_table_expand(row, expandedRows) {

                if (typeof this.clk_expand == "function")
                    this.clk_expand(row, expandedRows, this.$refs[this.ref])
            },

            //合计函数
            sum_method({columns, data}) {
                if (typeof this.table_sum_method === 'function')
                    return this.table_sum_method({columns, data})

                return this.default_sum_method({columns, data})
            },

            //默认合计函数
            default_sum_method({columns, data}) {
                const sums = [];
                columns.forEach((column, index) => {
                    if (index === 0) {
                        sums[index] = '合计'
                        return
                    }

                    const values = data.map(item => Number(item[column.property]));
                    if (!values.every(value => isNaN(value))) {
                        sums[index] = values.reduce((prev, curr) => {
                            const value = Number(curr)
                            if (!isNaN(value))
                                return prev + curr
                            else
                                return prev
                        }, 0)
                    }
                });

                return sums
            },

            // 查看更多
            view_detail() {

            }
        },
        watch: {
            'table_data': function () {
                this.$refs[this.table_ref].doLayout();//处理表格错位问题
                this.init_action();

            },
            deep: true,
            // immediate: true
        },
        computed: {
            actionsLength: function () {
                return this.table_action.options.filter((item) => item.is_show == true).length
            },

        }
    };
</script>


<style lang="less" scoped>
    .cell-span {
        display: block;
        width: 100%;
    }
    .input_span{
        display: block;
        width: 100%;
        min-height: 30px;
    }

    .edit-input {
        width: 100px !important;
        input {
            padding: 0 1% !important;
            text-align: center;
            display: inline-block;
        }
    }

    .table_expand {
        width: 97%;
        margin: 0 auto;
        padding-top: 0;
    }

    #append_info {
        .is-bordered-label {
            width: 100px;
            background-color: #e1f3d8;
            border: 1px solid #d9d9d9;
            text-align: center;
        }
    }

    .cell-overflow {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        /*word-wrap: break-word;*/
        text-align: left;

        /*overflow: hidden;*/
        /*text-overflow: ellipsis;*/
        /*!*white-space: nowrap;*!*/
        /*word-wrap: break-word;*/
        /*text-align: left;*/

    }

    .cell-overflow-elisp {
        display: inline-block;
        float: left;
    }

    .table-icon-up {
        position: absolute;
        top: 50%;
        transform: translate(0, -30%);
        color: #f56c6c;
    }

    .table-icon-down {
        position: absolute;
        top: 50%;
        transform: translate(0, -30%);
        color: #67c23a;
    }

    .demo-table-expand {
        font-size: 0;
    }

    .demo-table-expand label {
        /*width: 80px;*/
        color: #99a9bf;
        margin: 1px 10px 1px 50px;
    }

    .demo-table-expand .el-form-item {
        margin-right: 0;
        margin-bottom: 0;
        width: 100%;
    }

    .el-table {
        .el-table__header-wrapper, .el-table__fixed-header-wrapper {
            th {
                word-break: break-word;
                background-color: #f8f8f9;
                color: #515a6e;
                height: 40px;
                font-size: 13px;
                /*text-align: center;*/
            }
        }

        .el-table__body-wrapper {
            .el-button [class*="el-icon-"] + span {
                margin-left: 1px;
            }

            /*展开行*/

            .el-table__expanded-cell {
                z-index: 100;
            }
        }
    }


    /*媒体查询*/
    @media screen and (max-width: 1200px) {
        .cell-overflow-elisp {
            max-width: 40%;
        }
    }

    @media screen and (min-width: 1201px) {
        .cell-overflow-elisp {
            max-width: 80%;
        }
    }

</style>
